package com.rfid.udp;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;

import com.rfid.utils.UDPTool;

import lombok.extern.slf4j.Slf4j;

/**
 * UDP主动发送
 * 
 * 1.  明确对方的端口号， 向对方主动发送消息, 如心跳消息
 * 2.  不断接受到对方的回应
 */
@Slf4j
public class UDPPositive {

    private List<Integer> portList = new ArrayList<>();

	private DatagramSocket socket;

    private int port;

    private static final byte[] SEND_DATA_IP = {(byte)255,(byte)255,(byte)255,(byte)255};

    public UDPPositive() {
        super();
    }

    public UDPPositive(int port){
        this.port = port;
        init();
    }

    public void init(){
        try {
            this.socket = new DatagramSocket(port);
            log.debug("端口：{}，开启监听成功！", port);
        } catch (Exception e) {
            log.error("绑定udp端口异常！");
        }
    }

    /**
     * 接收线程
     */
    public void process() {
        new Thread(() -> {
            try {
                while (true) {
                    try {
                        receiveData();
                    } catch (Exception e){
                        log.error("接收线程退出{}",e);
                    }
                }
            } finally {
                if(null != socket){
                    socket.close();
                }
            }
        }).start();
    }

    /**
     * 接收数据
     */
    protected void receiveData(){
        try {
            //Map<String, String> result = new HashMap<String, String>();
            byte[] buffer = new byte[1024];
            DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
            log.debug("端口：{}，---开始接收--", this.port);
            if(null == this.socket){
                log.error("socket is null!");
            }
            this.socket.receive(packet);
            if(null == packet){
                log.error("packet is null!");
            }
            //添加数据解析方法
            int len = packet.getLength();
            byte[] data = packet.getData();
            if (len != 0) {
                byte[] send = new byte[len];
                System.arraycopy(data, 0, send, 0, len);
                if(!portList.contains(packet.getPort())){
                    portList.add(packet.getPort());
                }
                String hexString = UDPTool.toHexString(data, len);
                String time = UDPTool.getCurrentTime();
                log.debug("端口：{}，---接收到服务端的时间和数据--{}，内容:{}",
                        this.port, time ,hexString);
                sendData(packet.getPort(), send);
                //result.put("message", "---接收到服务端的时间和数据--" + time + "内容:" + hexString);
            }
        } catch (IOException e) {
            log.error("接收消息异常！", e);
        }
    }

    /**
     * 发送消息[这里以心跳为例]
     */
    public void sendUdpData(byte[] data){
    	//UDPTool.sendData(serverIP, serverPort, data, socket);
        log.debug(socket.getLocalPort() + "本地端口");
    }

    /**
     * udp send data
     * @param data
     * @throws IOException
     */
    public void sendData(int currentPort, byte[] data) throws IOException {
        for(Integer port : portList){
            if(currentPort != port){
                DatagramPacket packet = new DatagramPacket(data, data.length,
                        InetAddress.getByAddress(SEND_DATA_IP), port);
                log.debug("转发数据到端口：{}", port);
                this.socket.send(packet);
            }
        }
    }

}
